package br.unidocs.servico;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import br.unidocs.modelo.entidade.Arquivo;
import br.unidocs.modelo.entidade.Usuario;

/**
 * Session Bean implementation class UsuarioServicesImpl
 */
@Stateless
public class RelatorioEJBImpl implements RelatorioEJB {
	private static final String PROPERTIES_FILE = "/br/unidocs/servico/jasper.properties";

	@PersistenceContext(unitName = "UnidocsPU")
	EntityManager em; // inversao de controle , note a annotation. assim o
						// servidor injeta gerenciador de entidades

	private InputStream obterArquivoInterno(String nomeDoArquivo)
			throws IOException {
		String dir = null;
		String arquivo = null;

		URL url = null;

		url = RelatorioEJBImpl.class.getResource(PROPERTIES_FILE);

		InputStream properties = url.openStream();

		Properties jasperProperties = new Properties();
		jasperProperties.load(properties);

		dir = jasperProperties.getProperty("JASPER_BIN_DIR");
		arquivo = "/" + dir.replace('.', '/') + "/" + nomeDoArquivo;

		url = RelatorioEJBImpl.class.getResource(arquivo);

		if (url == null) {
			throw new RuntimeException("Arquivo [" + nomeDoArquivo
					+ "] não encontrado!");
		}
		InputStream arquivoStream = url.openStream();
		return arquivoStream;
	}

	public class DadoRelatorioArquivoPorUsuario {
		public String login;
		public String nomeUsuario;
		public String nomeArquivo;
		public Integer tamanhoArquivo;
		public Date dataUpload;

		public String getLogin() {
			return login;
		}

		public void setLogin(String login) {
			this.login = login;
		}

		public String getNomeUsuario() {
			return nomeUsuario;
		}

		public void setNomeUsuario(String nomeUsuario) {
			this.nomeUsuario = nomeUsuario;
		}

		public String getNomeArquivo() {
			return nomeArquivo;
		}

		public void setNomeArquivo(String nomeArquivo) {
			this.nomeArquivo = nomeArquivo;
		}

		public Integer getTamanhoArquivo() {
			return tamanhoArquivo;
		}

		public void setTamanhoArquivo(Integer tamanhoArquivo) {
			this.tamanhoArquivo = tamanhoArquivo;
		}

		public Date getDataUpload() {
			return dataUpload;
		}

		public void setDataUpload(Date dataUpload) {
			this.dataUpload = dataUpload;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public byte[] gerarRelatorioArquivosPorUsuario() {

		try {
			Collection<DadoRelatorioArquivoPorUsuario> col = new ArrayList<RelatorioEJBImpl.DadoRelatorioArquivoPorUsuario>();

			List<Usuario> usuarios = em.createQuery("select u from Usuario u")
					.getResultList();

			for (Usuario usuario : usuarios) {
				for (Arquivo arq : usuario.getArquivos()) {
					DadoRelatorioArquivoPorUsuario dado = new DadoRelatorioArquivoPorUsuario();
					dado.setDataUpload(arq.getDataUpload());
					dado.setLogin(usuario.getLogin());
					dado.setNomeArquivo(arq.getNome());
					dado.setNomeUsuario(usuario.getNome());
					dado.setTamanhoArquivo(arq.getTamanho());
					col.add(dado);
				}
			}

			JasperPrint jasperPrint = null;
			InputStream arquivo = obterArquivoInterno("arquivos_x_usuarios.jasper");

			JRDataSource dataSource = new JRBeanCollectionDataSource(col);
			//
			// if (col != null) {
			// dataSource = new JRBeanCollectionDataSource(col);
			// } else {
			// dataSource = new JREmptyDataSource();
			// }

			jasperPrint = JasperFillManager.fillReport(arquivo, null,
					dataSource);

			byte[] report = null;

			report = JasperExportManager.exportReportToPdf(jasperPrint);
			return report;
		} catch (JRException e) {
			throw new RuntimeException("Erro na geração do relatório.", e);
		} catch (IOException e) {
			throw new RuntimeException("Erro na I/O.", e);
		}
	}
}
